AI MUSIC FOR THE BEE
====================

A practical primer on AI-assisted polyphonic music for the Microbee
Updated through FURELIS3.COM and its cleaner time-division mixer


1. THE SURPRISING IDEA
----------------------

The Microbee has only a one-bit speaker output, but one bit does not limit it
to one musical note. The Z80 can calculate several independent square-wave
voices in software and combine their states before writing a single bit to the
speaker. The ear separates the resulting waveform back into distinct pitches.

This is software polyphony: the computer has one physical sound channel, but
the program maintains two or more virtual oscillators.

On a standard Microbee sound arrangement:

    Z80 PIO port B data register:  I/O port 02H
    Speaker output:                bit 6 (40H)

A CP/M music program normally begins at address 0100H. On a 3.375 MHz
Microbee, every instruction cycle matters because the Z80 itself is the sound
generator.


2. FIRST MAKE ONE VOICE WORK
----------------------------

The simplest tone generator repeatedly flips bit 6:

        IN      A,(02H)
        XOR     40H
        OUT     (02H),A

A timed delay between flips sets the frequency. If the complete half-wave loop
takes H Z80 T-states and the CPU clock is Fcpu, the approximate pitch is:

        frequency = Fcpu / (2 * H)

Do not copy timing values directly from a 3.5 MHz ZX Spectrum program. A later
Microbee commonly runs at 3.375 MHz, so the same instruction loop produces a
different pitch. Count the cycles or calculate new constants for the target
machine.

The first FURELISE.COM used this method. It proved that port 02H, bit 6 and the
emulator's speaker implementation were correct.


3. FOUR WAYS TO CREATE POLYPHONY
--------------------------------

A. Rapid arpeggiation

Play voice 1 for a tiny slice, then voice 2, then voice 3, and repeat. At a
high enough switching rate, the ear hears a chord. This method is easy and
cheap, but sustained notes may sound buzzy or unstable.

B. Countdown oscillators

Give each voice a counter and a reload value. Decrement every counter during
each mixer pass. When one reaches zero, flip that voice's state and reload its
counter. Combine all voice states into the speaker output.

This is well suited to an 8-bit processor and resembles several classic
one-bit music engines. Conditional reload paths can vary the loop timing,
however, so careful cycle balancing improves the sound.

C. Fixed-rate phase accumulators

This is the recommended method for clear two-voice Microbee music. Give each
voice a 16-bit phase and a 16-bit phase increment:

        phase = phase + increment

The top bit of the phase is the square-wave state. A small increment produces
a low note; a larger increment produces a high note. The mixer loop always
takes the same number of cycles, so tuning is predictable.

FURELISE2.COM and FURELIS3.COM use two 16-bit accumulators. One lives in the
normal HL/DE registers and the other in the alternate HL'/DE' registers. EXX
changes between them quickly.

D. Time-division output

Instead of mathematically combining two square-wave states, alternate their
speaker samples at a rate above normal hearing. Output one melody sample, then
one bass sample, and repeat with exactly even spacing. The ear receives the
average of both signals, while most of the switching energy lies around the
ultrasonic alternation rate.

This is the method adopted in FURELIS3 after listening tests showed that the
simultaneous OR mixer in FURELISE2 made the second voice sound raspy and warbly
in BeeWolf. Time division retains the accurate 16-bit phase accumulators but
changes how their top bits reach the one-bit speaker.


4. VERSION 2: THE SIMULTANEOUS OR MIXER
---------------------------------------

FURELISE2 advanced both phases during the same 87-cycle sample and ORed their
top bits before writing the speaker:

MIXLOOP:
        ADD     HL,DE           ; advance melody phase
        EXX
        ADD     HL,DE           ; advance accompaniment phase
        LD      A,H
        EXX
        OR      H               ; combine both phase bits
        AND     80H
        RRCA
MIXBASE:
        OR      00H             ; saved non-speaker PIO bits
        OUT     (02H),A
        DEC     BC
        LD      A,B
        OR      C
        JP      NZ,MIXLOOP

At 3.375 MHz this gives:

        sample rate = 3,375,000 / 87
                    = approximately 38,793.10 Hz

        increment = round(frequency * 65536 / 38793.10)

OR mixing is cheap and does retain both mathematical fundamentals, unlike XOR,
which produces strong sum-and-difference components. In practice, however,
the OR waveform has a 75 percent average high state and contains many mixed
harmonics. BeeWolf listening tests found that its accompaniment sounded too
raspy and warbly. This is an important engineering lesson: correct frequency
analysis does not guarantee pleasant one-bit sound. Listening tests remain
essential.


5. VERSION 3: THE CLEAN TIME-DIVISION MIXER
-------------------------------------------

FURELIS3 outputs the melody and bass separately. The two OUT instructions are
exactly 72 T-states apart. Six NOPs balance the first half of the loop against
the counter and branch instructions in the second half:

MIXLOOP:
        ADD     HL,DE              ; melody phase
        LD      A,H
        AND     80H
        RRCA
MIXBASE1:
        OR      00H
        OUT     (02H),A
        EXX
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP                        ; 24 T-states of balance

        ADD     HL,DE              ; bass phase
        LD      A,H
        AND     80H
        RRCA
MIXBASE2:
        OR      00H
        OUT     (02H),A
        EXX
        DEC     BC
        LD      A,B
        OR      C
        JP      NZ,MIXLOOP

One complete two-slot frame takes 144 T-states:

        physical speaker writes = 3,375,000 / 72
                                = 46,875 writes per second

        updates for each voice  = 3,375,000 / 144
                                = 23,437.5 updates per second

Use the per-voice update rate when calculating phase increments:

        increment = round(frequency * 65536 / 23437.5)

Equivalent Microbee-specific form:

        increment = round(frequency * 65536 * 144 / 3375000)

Working FURELIS3 values include:

        E2    82.41 Hz  ->  230
        G#2  103.83 Hz  ->  290
        A2   110.00 Hz  ->  308
        C4   261.63 Hz  ->  732
        E4   329.63 Hz  ->  922
        A4   440.00 Hz  -> 1230
        B4   493.88 Hz  -> 1381
        C5   523.25 Hz  -> 1463
        E5   659.26 Hz  -> 1843

A numerical spectrum check of a representative B4 plus E2 event showed the
two strongest audible components at 493.88 Hz and 82.25 Hz, with neither a
dominant low-frequency difference tone nor the OR mixer's heavy interaction.

For melody-only events, FURELIS3 copies the melody increment into both phase
accumulators. Both alternating slots then carry the same waveform, preventing
the solo melody from becoming thin or half-volume.

Time division does not make a one-bit speaker identical to a multi-channel
DAC, but it gives a cleaner and more predictable two-voice result. For three or
four voices, consider majority mixing, weighted time slots, pulse-density
mixing, or a specialised beeper engine.


6. PRESERVE THE REST OF PIO PORT B
----------------------------------

Never assume that every other bit on port 02H is disposable. Capture the port
state and clear only the speaker bit:

        IN      A,(02H)
        AND     0BFH
        LD      (MIXBASE1+1),A
        LD      (MIXBASE2+1),A

MIXBASE1 and MIXBASE2 are OR-immediate instructions. Patching their operands
makes the fast time-division mixer restore the saved non-speaker bits on every
OUT without adding a slow memory lookup to each sample.

On exit, force the speaker low while preserving the other bits:

SPEAKEROFF:
        IN      A,(02H)
        AND     0BFH
        OUT     (02H),A
        RET

This also prevents an unpleasant stuck click or DC speaker state after the
program returns to CP/M.


7. REPRESENTING MUSIC AS DATA
-----------------------------

Keep the player separate from the music. A compact two-voice event can contain:

        melody increment
        accompaniment increment
        duration in mixer samples or two-slot frames

For example:

        DW      E5,0,DUR1
        DW      DS5,0,DUR1
        DW      E5,0,DUR1
        DW      B4,E2,DUR1
        DW      D5,A2,DUR1
        DW      C5,E2,DUR1
        DW      A4,A2,DUR2

In FURELIS3, zero accompaniment means the melody step is copied into the second
time slot. The listener hears a clean, full melody rather than silence in every
other output slot. Nonzero lower notes enter later, creating the impression of
another instrument or the pianist's left hand.

FURELIS3 is 30 percent slower than version 2. Its short-note unit is 195 ms,
including a 12 ms gap. Because duration counts are two-slot frames at 23,437.5
frames per second:

        tone frames = round((0.195 - 0.012) * 23437.5)
                    = 4289

The version 3 duration values are:

        DUR1 =  4289     about 195 ms including gap
        DUR2 =  8859     about 390 ms including gap
        DUR4 = 18000     about 780 ms including gap

FURELIS3 treats a zero melody increment as the end marker. If rests are
required, change the format so a zero duration ends the tune; a melody
increment of zero can then mean silence.


8. ARRANGING MUSIC FOR ONE-BIT SOUND
------------------------------------

Normal piano arrangements are often too dense for a beeper. Reduce them to the
musical information that matters most:

    Voice 1: the recognisable melody.
    Voice 2: bass roots, fifths or a broken-chord accompaniment.

Good one-bit arrangements use space. Begin with melody alone, bring in the
second voice for emphasis, and avoid holding two nearby high notes for too
long. Widely separated pitches are usually clearer than close intervals.

For Fur Elise, a useful plan is:

    * play the E5/D#5 opening pickup alone;
    * enter E2, A2 and E2 beneath B4, D5 and C5;
    * support the A-minor cadence with A2;
    * use E2 and G#2 beneath the E-major answering phrase;
    * return to A2 for the final cadence.

Moving the accompaniment mainly into octave 2 gives it greater separation from
the melody and was another response to the version 2 listening test.

FURELIS3 repeats the 43-unit opening-and-cadence arrangement fourteen times.
At 195 ms per unit this gives approximately:

        43 * 0.195 * 14 = 117.39 seconds

That is about 1 minute 57 seconds, close to the requested two-minute version.
A one-byte pass counter restarts the music table without duplicating fourteen
copies in the .COM file.


9. HOW AI HELPS
---------------

AI is most useful as a composer, arranger and code generator outside the
Microbee. The resulting tables and player are then assembled into a small,
self-contained CP/M program.

A practical AI-assisted workflow is:

    1. Give the AI the melody as notes, MIDI data or a public-domain score.
    2. State the target clock, sample-loop cycle count and number of voices.
    3. Ask for a reduced melody-and-bass arrangement suitable for one bit.
    4. Generate exact phase increments with the formula above.
    5. Generate duration sample counts from the desired tempo.
    6. Ask for a Z80 DW event table, not prose note names.
    7. Assemble at 0100H as a flat CP/M .COM binary.
    8. Test first in BeeWolf, then on real hardware if available.
    9. Report whether pitch, tempo, balance or note order sounds wrong.
   10. Regenerate only the constants or table that need adjustment.

An effective prompt might be:

    "Arrange this melody for a 3.375 MHz Microbee using two 16-bit phase
    accumulators and an evenly balanced 144-cycle two-slot time-division
    mixer. Keep the melody in voice 1, write a sparse octave-2 bass part in
    voice 2, use 195 ms as the short unit, and output Z80 DW records containing
    melody step, bass step and frame count."

AI-generated music data must still be checked by ear. Common mistakes include
wrong octaves, incorrect accidentals, over-busy accompaniment, copied timing
for a different CPU clock, and a note table that does not match the player's
record layout. User listening feedback is especially valuable: "raspy and
warbly" led directly from the OR mixer to the cleaner time-division design,
while "too fast" led to measured changes from 125 ms to 150 ms and finally
195 ms per short rhythmic unit.


10. CP/M AND REAL-MACHINE DISCIPLINE
------------------------------------

Keep BDOS calls outside the sample loop. Printing text or checking the keyboard
inside the loop destroys the fixed sample timing. FURELIS3 checks for a key
only between musical events.

Useful CP/M conventions are:

    ORG 0100H              standard .COM load and entry address
    CALL 0005H, C=09H      print a $-terminated string
    CALL 0005H, C=0BH      test console status
    CALL 0005H, C=01H      consume a waiting character
    RET                    return to CCP when the original stack is intact

Preserve the tune pointer around BDOS calls rather than assuming every BDOS
implementation keeps HL unchanged.

Interrupts can introduce occasional timing jitter. Do not automatically place
DI around a complete song: some Microbee configurations or peripherals may
depend on interrupts. First test with the normal system state. Disable or
manage interrupts only when the exact model, BIOS and restoration requirements
are understood.


11. DEBUGGING CHECKLIST
-----------------------

If there is no sound:

    * confirm the PIO is configured appropriately by the running system;
    * confirm output is going to port 02H and bit 6;
    * test a single slow toggle loop before testing the mixer;
    * confirm the .COM file loads at 0100H;
    * check that the tune does not immediately encounter its end marker.

If the pitch is wrong:

    * confirm the actual CPU clock;
    * recount the mixer-loop T-states;
    * recalculate every phase increment;
    * make sure interrupts are not dominating the timing.

If the second voice sounds rough:

    * lower it by an octave;
    * use fewer accompaniment notes;
    * try roots and fifths rather than close thirds;
    * alternate melody-only and two-voice passages;
    * replace simultaneous OR/XOR mixing with evenly timed time division;
    * keep the two OUT instructions equally spaced in Z80 T-states;
    * duplicate melody into both slots when accompaniment is zero;
    * inspect a generated waveform spectrum as well as listening by ear.

If the tempo is wrong, change duration sample counts, not phase increments.
Pitch and rhythm are independent in a fixed-rate phase player.


12. WHERE TO GO NEXT
--------------------

Once the two-voice engine is reliable, useful extensions include:

    * a proper rest and end-marker format;
    * dotted notes, triplets and tempo changes;
    * volume illusion through duty-cycle control;
    * vibrato by gently changing the phase increment;
    * envelopes for plucked or piano-like attacks;
    * three voices using a balanced one-bit mixer;
    * a PC-side converter from MIDI or MusicXML to Microbee DW tables;
    * compressed patterns and pass counters for longer songs;
    * model-specific tables for different Microbee clock speeds.

The important principle is simple: the Microbee speaker remains one bit, but
the Z80 can calculate a whole small ensemble before deciding what that bit
should be. With disciplined cycle timing, sparse arrangements and AI-assisted
table generation, the 'bee can make music far beyond a single beep.


Companion examples:

    FURELISE.COM   - monophonic delay-loop proof of concept
    FURELISE.ASM   - source for the monophonic player
    FURELISE2.COM  - slower two-voice phase-accumulator edition
    FURELISE2.ASM  - source for the polyphonic player
    FURELIS3.COM   - 1:57 cleaner time-division two-voice edition
    FURELIS3.ASM   - source for the balanced 72-T-state output mixer
